<?php

namespace App\System\Log\Repositories;

use App\Module\Api\Controllers\Request\PaySubmitRequest;
use App\System\Base\Helpers\Traits\SinglePattern;
use App\System\Base\Repositories\Repository;
use App\System\Base\Services\NotifyService;
use App\System\Base\Services\PayService;
use App\System\Base\Services\TokenService;
use App\System\Cis\Repositories\CisUserRepository;
use App\System\Fina\Repositories\FinaIntegralRegRecordRepository;
use App\System\Log\Model\LogPay;
use App\System\Order\Repositories\OrderInfoRepository;
use Illuminate\Support\Facades\DB;

class LogPayRepository extends Repository
{
    use SinglePattern;

    /**
     * api 生成财务记录，及第三方日志记录
     * @param PaySubmitRequest $paySubmitRequest
     * @param $user_id
     */
    public function addData(PaySubmitRequest $paySubmitRequest,$user_id)
    {
        DB::beginTransaction();
        $log_set = ['trade_no'=>$this->generateTradeNo(),
                    'payment_type'=>$paySubmitRequest->payType,
                    'cash'=>$paySubmitRequest->cash,
                    'status'=>3];
        $fina_set = ['income'=>2,
                     'type'=>$paySubmitRequest->action,
                     'record_type'=>1,
                     'status'=>3,
                     'after_cash'=>0,
                     'commission'=>0,
                     'user_id'=>$user_id
                    ];
        $user = CisUserRepository::getInstance();
        $fina = FinaIntegralRegRecordRepository::getInstance();
        if($paySubmitRequest->action == 2)
        {//订单支付

            $order = OrderInfoRepository::getInstance();
            $order_info = $order->getOne($paySubmitRequest->id,$user_id);
            if(!$order_info || $order_info['status'] != 1)
            {//订单不存在，或不是待支付状态
                return ['s'=>'10000','d'=>'待支付订单不存在'];
            }
            if($order_info['payAmount'] == 0)
            {//金额为0，并且为待支付直接调用回调执行更新业务
                $res = NotifyService::orderNotify($order_info->id,3);
                if(!$res)
                {
                    return ['s'=>'0','d'=>'系统错误，操作失败，请稍后在试'];
                }
                else
                {
                    DB::commit();//提交事务
                    return ['s'=>'0','d'=>'操作成功','id'=>$order_info['id']];
                }


            }
            $cash = $order_info['payAmount'];
            $body = '订单支付'.$cash.'元';
            if($paySubmitRequest->payType == 3)
            {//余额支付判断是当前积分是否足够支付

                $user_info = $user->getUser($user_id);
                if(!$user_info) return ['s'=>'10000','d'=>'用户不存在'];
                $master_id = TokenService::getMasterId();
                $master_info = $user->getUser($master_id);
                if($master_info->pay_password != $paySubmitRequest->payPassword) return ['s'=>'10000','d'=>'支付密码错误，请重新输入'];
                if($user_info->integral < $order_info['payAmount'])
                {
                    return ['s'=>'10000','d'=>'付款失败，钱包积分不足'];
                }
            }
            $fina_info = $fina->getOrderFina($paySubmitRequest->id,$user_id);
            if(!$fina_info)
            {//没有生成财务记录,则生成支付财务记录
                $fina_set['order_id'] = $paySubmitRequest->id;
                $fina_set['cash'] = $order_info['payAmount'];
                if($paySubmitRequest->payType != 3)
                {
                    $log_set['cash'] = $order_info['payAmount'];
                    $trade_no = $log_set['trade_no'];//支付流水号
                    $fina_set['type'] = 1;
                    $fina_set['income'] = 1;
                    $ids = $this->createLogPayAndFina($log_set,$fina_set);//在生成一条充值记录及第三方支付记录
                    if(!$ids)
                    {
                        return ['s'=>'10000','d'=>'财务记录生成失败'];
                    }

                    $fina_set['pay_id'] = $ids['pay_id'];
                }
                $fina_set['income'] = 2;
                $fina_set['type'] = 2;
                $fila_id_one  = $fina->createFina($fina_set);//生成一条订单支付记录
                if(!$fila_id_one)
                {
                    return ['s'=>'10000','d'=>'财务记录生成失败'];
                }

                if($paySubmitRequest->payType == 3)
                {
                    //扣除用户钱包对的积分
                    $res = $user->updateUserPurse($user_id,2,'integral',$order_info['payAmount']);
                    if(!$res)
                    {
                        return ['s'=>'10000','d'=>'操作失败，扣款失败'];
                    }
                    $res = NotifyService::orderNotify($order_info['id'],3);
                    if(!$res)
                    {
                        return ['s'=>'0','d'=>'系统错误，操作失败，请稍后在试'];
                    }
                    else
                    {
                        DB::commit();//提交事务
                        return ['s'=>'0','d'=>'操作成功','id'=>$order_info['id']];
                    }
                }

            }
            else
            {
                if($fina_info->status !=3)
                {
                    return ['s'=>'1000','d'=>'此订单状态不允许支付'];
                }
                if($paySubmitRequest->payType == 3)
                {
                    //扣除用户钱包对的积分
                    $res = $user->updateUserPurse($user_id,2,'integral',$order_info['payAmount']);
                    if(!$res)
                    {
                        return ['s'=>'10000','d'=>'操作失败，扣款失败'];
                    }
                    $res = NotifyService::orderNotify($order_info['id'],3);
                    if(!$res)
                    {
                        return ['s'=>'0','d'=>'系统错误，操作失败，请稍后在试'];
                    }
                    else
                    {
                        DB::commit();//提交事务
                        return ['s'=>'0','d'=>'操作成功','id'=>$order_info['id']];
                    }
                }

                if(!$fina_info->pay_id)
                {
                    $log_set['cash'] = $order_info['payAmount'];
                    $trade_no = $log_set['trade_no'];//支付流水号
                    $pay_id = $this->createLogPay($log_set);
                    if(!$pay_id)
                    {
                        return ['s'=>'10000','d'=>'支付记录生成失败'];
                    }
                    $fina_info = $fina->updateFina(['pay_id'=>$pay_id,'cash'=>$order_info['payAmount']],$fina_info->id);
                    if(!$fina_info)
                    {
                        return ['s'=>'10000','d'=>'财务记录生成失败'];
                    }

                }
                else
                {
                    if($fina_info->cash != $order_info['payAmount'])
                    {//如果修改过订单,要更新订单金额
                        $fina_info = $fina->updateFina(['cash'=>$order_info['payAmount']],$fina_info->id);
                        if(!$fina_info)
                        {
                            return ['s'=>'10000','d'=>'财务更新失败'];
                        }
                    }
                    $trade_no = $this->generateTradeNo();
                    $res = $this->updateLogPay(['trade_no'=>$trade_no,'payment_type'=>$paySubmitRequest->payType],$fina_info->pay_id);
                    if(!$res)
                    {
                        return ['s'=>'10000','d'=>'财务流水号更新失败'];
                    }
                }

            }
        }
        elseif($paySubmitRequest->action ==1)
        {//充值积分
            if($paySubmitRequest->payType>2) return ['s'=>'10000','d'=>'支付类型错误'];

            $log_set['cash'] = $paySubmitRequest->cash;
            $body = '积分充值支付'.$log_set['cash'].'元';
            $cash = $log_set['cash'];
            $trade_no = $log_set['trade_no'];//支付流水号
            $fina_set['type'] = 1;
            $fina_set['income'] = 1;
            $fina_set['cash'] = $cash;
            $ids = $this->createLogPayAndFina($log_set,$fina_set);
            if(!$ids)
            {
                return ['s'=>'10000','d'=>'财务记录生成失败'];
            }
        }

        DB::commit();
        $pay = new PayService();
        if($paySubmitRequest->payType == 1)
        {
            $res = $pay->WxPay(['body'=>$body,'out_trade_no'=>$trade_no,"total_fee"=>$cash]);

            return ['s'=>0,'d'=>'操作成功','wxPay'=>$res,'id'=>$paySubmitRequest->id];
        }
        else
        {
            $res = $pay->AliPay(['subject'=>$body,'out_trade_no'=>$trade_no,"total_amount"=>$cash]);
            return ['s'=>0,'d'=>'操作成功','alipay'=>$res,'id'=>$paySubmitRequest->id];
        }

    }

    /**
     *生成一条支付日志
     * @param array $set 数据
     * @return int
     */
    public function createLogPay(array $set)
    {
        $res = LogPay::create($set);
        if(!isset($res->id))
        {
            return false;
        }
        return $res->id;
    }


    /**
     * 更新支付记录
     * @param array $set
     * @param $id
     * @return bool
     */
    public function updateLogPay(array $set,$id)
    {
        $res = LogPay::where('id',$id)->update($set);
        return $res;
    }


    /**
     * 生成支付记录同时生成财务记录,适合于第三方支付
     * @param array $pay_set
     * @param array $fina_set
     * @return array|bool
     */
    public function createLogPayAndFina(array $pay_set,array $fina_set)
    {
       $pay_id =  $this->createLogPay($pay_set);
       if(!$pay_id)
       {
           return false;
       }
       $fina = FinaIntegralRegRecordRepository::getInstance();
       $fina_set['pay_id'] = $pay_id;
       $fina_id = $fina->createFina($fina_set);
       if(!$fina_id)
       {
            return false;
       }
       return ['pay_id'=>$pay_id,'fina_id'=>$fina_id];
    }

    /**
     * 生成流水号
     */
    private function generateTradeNo()
    {
        return date("YmdHis").mt_rand(100000,999999);
    }

    /**
     * 获取一条支付日志
     * @param $tradeNo 支付流水号
     *
     */
    public function getOne($tradeNo)
    {
        return LogPay::where('trade_no',$tradeNo)->where('status',3)->first();
    }
}